<FONT SIZE="+4" COLOR="#0000AF">C</FONT>olorSync 2.6 is the latest version of Apple Computer's color management architecture for Mac OS, Windows 95/98, and Windows NT 4.0. This Technote describes in detail the changes in this new version of ColorSync. This note is primarily intended for developers who are using the ColorSync APIs.
<P>ColorSync 2.6 for Macintosh requires a PowerPC machine running Mac OS 8.1 or later. ColorSync 2.6 for Windows requires an IBM-compatible PC running Windows 95/98 or Windows NT 4.0.</P>
</TD></TR>
</TABLE>
<BR>
<p id=p1>
<a href="#top">Back to top</a>
</p>
<TABLE BORDER=0 CELLPADDING=1 width=550>
<TR>
<TD>
<A NAME="Checking"></A>
<H2>Checking for ColorSync 2.6</H2>
<P><B>Macintosh</B><BR>
<BR>
To determine if the ColorSync Manager shared libraries have been loaded on a PowerPC machine, use the <CODE>Gestalt</CODE> function with the <CODE>gestaltColorMatchingAttr</CODE> selector. Test the bit field (bit 1) indicated by the <CODE>gestaltColorMatchingLibLoaded</CODE> constant in the response parameter. If the bit is set, the ColorSync Manager shared libraries are loaded. The following code snippet shows how this is done. This code snippet initializes the <CODE>ColorSyncAvailable</CODE> Boolean variable to <CODE>false</CODE>.</P>
To check for the presence of ColorSync under Windows 95/98 and Windows NT, use the new ColorSync 2.6 function <CODE>CMGetColorSyncVersion</CODE> (see the section "<A HREF="#NewAPIs">New ColorSync 2.6 APIs</A>" below for the details). ColorSync will first attempt to load the ColorSync DLLs if you call this function on a Windows system. If the ColorSync DLLs can't be loaded, an error code will be returned, indicating ColorSync is not present.
</P>
<P>
The <CODE>CMGetColorSyncVersion</CODE> function also returns the ColorSync version information. Here's a code snippet that checks for ColorSync version 2.6 on Windows:
</P>
</TD>
</TR>
</TABLE>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
#define kColorSync26 0x00000260
CMError err;
UInt32 version;
err = CMGetColorSyncVersion(&version);
if (err == noErr)
{
if (version >= kColorSync26)
{
/* ColorSync 2.6 or better is installed */
}
}
else
{
/* ColorSync not present */
}</PRE>
</TD>
</TR>
</TABLE>
<BR>
<p id=p1>
<a href="#top">Back to top</a>
</p>
<BR>
<TABLE BORDER=0 CELLPADDING=1 width=550>
<TR>
<TD>
<A NAME="Gettinginfo"></A>
<H2>Getting ColorSync 2.6 Version Information</H2>
<P><B>Windows</B><BR>
<BR>
As described in the section "<A HREF="#Checking">Checking for ColorSync 2.6</A>", use the new ColorSync 2.6 function <CODE>CMGetColorSyncVersion</CODE> to get ColorSync version information on machines running Windows 95/98 & Windows NT 4.0.<BR>
<BR>
<B>Macintosh</B><BR>
<BR>
As described in the section "<A HREF="#Checking">Checking for ColorSync 2.6 - Windows</A>", use the new ColorSync 2.6 function <CODE>CMGetColorSyncVersion</CODE> to get ColorSync version information on the Macintosh.<BR>
<BR>
</P>
</TD></TR>
</TABLE>
<BR>
<TABLE BORDER=0 CELLPADDING=1 width=550>
<TR>
<TD bgcolor="eeeee0">
<P><B>Important Note:</B><BR>
On Macintosh systems with ColorSync 2.6 installed, the <CODE>CMGetColorSyncVersion</CODE> function returns the value <CODE>0x00026000</CODE> in the version field. However, on a Windows
system with ColorSync 2.6 installed, the same <CODE>CMGetColorSyncVersion</CODE> function returns the value <CODE>0x00000260</CODE>, which is consistent with <CODE>Gestalt</CODE> return values. Future versions of ColorSync 2.6 on the Macintosh will correct this problem and return values which are consistent with <CODE>Gestalt</CODE>.<BR>
<BR>
Alternately, you can use the <CODE>Gestalt</CODE> function with the <CODE>gestaltColorMatchingVersion</CODE> selector to get ColorSync version information on the Macintosh.<BR>
<BR>
You can modify and use the following sample code to test for version 2.6 of the ColorSync Manager. This function initializes the Boolean variable <CODE>ColorSyncAvailable</CODE> to <CODE>false</CODE> and sets it to <CODE>true</CODE> if version 2.6 or later of the ColorSync Manager is installed.
</TD></TR>
</TABLE>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>#define kColorSync26 0x00000260
Boolean CheckForColorSyncMacVersion26(void)
{
Boolean ColorSyncAvailable = false;
long version;
if (Gestalt(gestaltColorMatchingVersion, &version) == noErr)
{
if (version >= kColorSync26)
{
ColorSyncAvailable = true;
}
}
return ColorSyncAvailable;
}</PRE>
</TD>
</tr>
</table>
<BR>
<p id=p1>
<a href="#top">Back to top</a>
</p>
<TABLE BORDER=0 CELLPADDING=1 width=550>
<TR>
<TD>
<A NAME="NewAPIs"></A>
<H2>New ColorSync 2.6 APIs</H2>
<P>The following new APIs were added to ColorSync 2.6:</P>
<TD valign=top>prof</TD><TD valign=top>A reference to the profile from which to obtain the desc tag info.</TD>
</TR>
<TR>
<TD valign=top>aName</TD><TD valign=top>A pointer to a field which is to receive the profile name as a 7-bit Roman ASCII string.</TD>
</TR>
<TR>
<TD valign=top>aCount</TD><TD valign=top>A pointer to a field which is to receive a count of the number of characters returned in the aName field above.</TD>
</TR>
<TR>
<TD valign=top>mName</TD><TD valign=top>A pointer to a field which is to receive the localized profile name string in Mac script-code format.</TD>
</TR>
<TR>
<TD valign=top>mCode</TD><TD valign=top>A pointer to a field which is to receive the script code corresponding to the name string returned in the mName parameter above.</TD>
</TR>
<TR>
<TD valign=top>uName</TD><TD valign=top>A pointer to a field which is to receive the Unicode localized profile name string.</TD>
</TR>
<TR>
<TD valign=top>uCount</TD><TD valign=top>A pointer to a field which is to receive a count of the number of Unicode (2-byte) characters returned in the uName field above.</TD>
<TD valign=top>prof</TD> <TD valign=top>A reference to the profile into which to set the desc tag info.</TD>
</TR>
<TR>
<TD valign=top>aName</TD> <TD valign=top>A pointer to a field containing a 7-bit Roman ASCII profile name string which is to be set for the profile. This string must be null-terminated.</TD>
</TR>
<TR>
<TD valign=top>aCount</TD> <TD valign=top>A count of the number of characters in the aName field above.</TD>
</TR>
<TR>
<TD valign=top>mName</TD> <TD valign=top>A pointer to a field containing the localized profile name string in Mac script-code format which is to be set for the profile. This string must be null-terminated.</TD>
</TR>
<TR>
<TD valign=top>mCode</TD> <TD valign=top>The script code corresponding to the name string in the mName parameter above.</TD>
</TR>
<TR>
<TD valign=top>uName</TD> <TD valign=top>A pointer to a field containing the Unicode localized profile name string which is to be set for the profile. This string must be null-terminated.</TD>
</TR>
<TR>
<TD valign=top>uCount</TD> <TD valign=top>A count of the number of Unicode characters in the uName field above (do not confuse this with a byte count, because each Unicode character requires two bytes).</TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</B><BR>
<P>
Use these functions to get/set the description tag data for a given profile. The ICC Profile Format Specification (available at <<A HREF="http://www.color.org">http://www.color.org</A>>) includes a Description tag (<CODE>'desc'</CODE>), designed to provide more information about a profile than can be contained in a file name. This is especially critical on file systems with 8.3 names. The tag data can consist of up to three separate pieces (strings) of information
for a profile. These different strings are designed to allow for display in different languages or on different computer systems. Applications typically use one of the strings to show profiles in a list or a pop-up menu. ColorSync 2.6 includes these new APIs for accessing this information, and also checks for the validity of the <CODE>'desc'</CODE> tag according to the ICC Spec.<BR>
</P>
</td>
</tr>
</table>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
CMError NCWConcatColorWorld (CMWorldRef *cw,
NCMConcatProfileSet *profileSet,
CMConcatCallBackUPP proc,
void *refCon);
</PRE>
</TD>
</tr>
</table>
<BR>
<B>Field Descriptions</B><BR>
<BR>
<TABLE width=550 border="1">
<TR>
<TD valign=top>cw</TD> <TD valign=top>A reference to a color world that the ColorSync Manager returns if the function completes successfully. You pass this reference to other functions that use the color world for color-matching and color-checking sessions.</TD>
</TR>
<TR>
<TD valign=top>profileSet</TD> <TD valign=top>An array of profiles describing the processing to be carried out. The array is in processing order source through destination.</TD>
</TR>
<TR>
<TD valign=top>proc</TD> <TD valign=top>A calling-program-supplied callback function that allows your application to monitor progress or abort the operation.</TD>
</TR>
<TR>
<TD valign=top>refCon</TD> <TD valign=top>A reference constant containing data specified by the calling application program.</TD>
</TR>
</TABLE>
<BR>
<B>New structures for use with this function:</B><BR>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
struct NCMConcatProfileSet {
OSType cmm; /* e.g., 'KCMS'. Uniquely IDs the CMM, or 0000 */
unsigned long flags; /* specify quality */
unsigned long flagsMask; /* which bits of flags to use to override profile.
*/
unsigned long profileCount; /* how many ProfileSpecs in the following set */
NCWConcatProfileSpec profileSpecs[]; /* A new structure, defined below */
};
struct NCWConcatProfileSpec {
unsigned long renderingIntent; /* intent to use along with transformTag. */
unsigned long transformTag; /* one of a set of tag identifiers, defined below
*/
CMProfileRef profile; /* the profile to extract the transform from */
};
enum {
kNoTransform = 0, /* Not used */
kUseAtoB = 1, /* Use 'A2B*' tag from this profile or equivalent */
kUseBtoA = 2, /* Use 'B2A*' tag from this profile or equivalent */
kUseBtoB = 3, /* Use 'pre*' tag from this profile or equivalent */
/* For typical device profiles the following synonyms may be useful */
kDeviceToPCS = kUseAtoB, /* Device Dependent to Device Independent */
kPCSToDevice = kUseBtoA, /* Device Independent to Device Dependent */
kPCSToPCS = kUseBtoB, /* Independent, through device's gamut */
/* This is provided for default behavior when specifying rendering intent in the NCMConcatProfileSpec
*/
kUseProfileIntent = (long)0xFFFFFFFF
/* For renderingIntent in NCMConcatProfileSpec*/
};
/*
Caller-supplied progress function for NCMMConcatInit & NCMMNewLinkProfile routines
The <CODE>NCWConcatColorWorld</CODE> function defines a color world for color transformations among a series of concatenated
profiles. The caller can override the CMM that would normally be selected by ColorSync by providing a CMM identifier in the <CODE>NCMConcatProfileSet</CODE> structure, or pass 0 to accept ColorSync's CMM selection (note that this could either be the user's preferred CMM selection or the CMM called for in the profile). The <CODE>flags</CODE> and <CODE>flagsMask</CODE> parameters are provided to allow easy customization of such attributes as quality and gamut-checking, while preserving the other settings. Each profile in the set can be customized by overriding the intent, and the selection of the transform tag. Together with other profiles, a custom-rendering environment can be set up to transform to or from device-dependent spaces with a minimum of gamut compression and/or unnecessary transformations to and from connection spaces. This flexibility comes at the price of specific knowledge of the profile contents and how device gamuts overlap.
</P>
<P>
Note that for standard input and output device profiles, <CODE>A2B</CODE> and <CODE>B2A</CODE> tags represent transforms from data space to connection space and from connection space to data space, respectively. Under these circumstances, the caller would not normally be able to use the same transform tags (e.g., <CODE>kUseAtoB</CODE>) consecutively, since a connection space would not be the same as the subsequent data space. If the spaces aren't the same, the caller will get a <CODE>cmCantConcatenateError</CODE> error (-178) returned. For profiles of type <CODE>cmLinkClass, cmAbstractClass, cmColorSpaceClass</CODE>, and <CODE>cmNamedColorClass</CODE>, these constants are not always meaningful, and the caller is encouraged to think in terms of the actual tags present in the profiles (e.g., <CODE>A2B0</CODE> or <CODE>B2A0</CODE>). Under these conditions, it may well be appropriate to specify two transform tags of the same type consecutively, as long as the actual color spaces align in between tags. If this is not the case, a <CODE>cmCantConcatenateError</CODE> error (-178) is returned.
</P>
<P>
The <CODE>Callback</CODE> proc is provided as protection against the appearance of a stalled machine during lengthy color world processing. If a CMM takes more than several seconds to process the information and create a color world, it will call the <CODE>Callback</CODE> proc, if one is provided, and pass it the <CODE>refCon</CODE> provided. This is also true for <CODE>NCWNewLinkProfile</CODE>, described below:
<TD valign=top>The returned profile reference.</TD>
</TR>
<TR>
<TD valign=top>targetLocation</td>
<TD valign=top>The location of the profile, which you specify using the <CODE>CMProfileLocation</CODE> data type. Commonly a profile is disk-file based. However, the profile may be a file-based profile, a handle-based profile, or a pointer-based profile.</TD>
</TR>
<TR>
<TD valign=top>profileSet</TD>
<TD valign=top>The profile set structure.</TD>
</TR>
<TR>
<TD valign=top>proc</TD>
<TD valign=top>A calling-program-supplied callback function that allows your application to monitor progress or abort the operation.</TD>
</TR>
<TR>
<TD valign=top>refCon</TD>
<TD valign=top>A reference constant containing data specified by the calling application program.</TD>
</TR>
</TABLE>
<BR>
<TABLE>
<TR>
<TD width=550>
<B>DESCRIPTION</B><BR>
<BR>
<P>
The same new flexibility in creating color worlds is extended to link profiles, which are now not assumed to go from input device color space to output device color space. The returned profile is open, and should be closed when you are finished with it.
<TD valign=top>profLoc</td> <TD valign=top>The location of the profile, which you specify using the <CODE>CMProfileLocation</CODE> data type. Commonly a profile is disk-file based. However, the profile may be a file-based profile, a handle-based profile, or a pointer-based profile.
</td>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</B><BR>
<BR>
<P>
Prior to ColorSync 2.6, the API for setting the System Profile supported only the <CODE>FSSpec</CODE> file specification type as a way of specifying a profile. This new API is designed to address Windows file systems specifications as well.
<TD valign=top>The location of the profile you wish to unflatten, which you specify using the <CODE>CMProfileLocation</CODE> data type. Commonly a profile is disk-file based. However, the profile may be a file-based
profile, a handle-based profile, or a pointer-based profile.</td>
</TR>
<TR>
<TD valign=top>proc</td>
<TD valign=top>A user-defined procedure which is called during the unflatten operation.</td>
</TR>
<TR>
<TD valign=top>refCon</td>
<TD valign=top>A reference constant containing data specified by the calling application program.</td>
</TR>
<TR><TD valign=top>preferredCMMnotfound</td>
<TD valign=top>A return value indicating whether or not the CMM specified in the profile was found.</td>
</TR></TABLE>
<BR>
<B>DESCRIPTION</B><BR>
<BR>
Use this function to unflatten a profile.<BR>
<BR>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
CMError CMIterateCMMInfo (CMMIterateUPP proc,
UInt32 *count,
void *refCon);
</PRE>
</TD>
</tr>
</table>
<BR>
<B>Field Descriptions</B><BR>
<BR>
<TABLE width=550 border = "1">
<TR>
<TD valign=top>proc</TD> <TD valign=top>A calling-program-supplied callback function that allows your application to monitor progress or abort the operation.<BR></TD>
</TR>
<TR>
<TD valign=topD>count</TD> <TD valign=top>A count of the number of CMMs referenced is returned here.<BR></TD>
</TR>
<TR>
<TD valign=top>refCon</TD> <TD valign=top>A reference constant containing data specified by the calling application program.</TD>
</TR>
</TABLE>
<BR>
<B>NEW STRUCTURES FOR USE WITH THIS FUNCTION</B><BR>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
OSErr CMMIterateUPP(
CMMInfo* iterateData, /* Ptr to a structure containing
/* information about a particular CMM */
void* refcon /* Caller-defined data, passed through from CMIterateCMMInfo
API */
);
struct CMMInfo {
unsigned long dataSize; /* Size of this structure - for compatibility */
OSType CMMType; /* Signature of CMM */
OSType CMMMfr; /* Vendor, e.g. 'appl */
unsigned long CMMVersion; /* Version number */
Handle CMMIcons; /* If available, can be a group with varying size
& depth */
unsigned char ASCIIName[32]; /* Pascal string - name */
UniCharCount UniCodeNameCount; /* Count of UniChars in following array */
UniChar UniCodeName[32]; /* The name in UniCode chars */
UniCharCount UniCodeDescCount; /* Count of UniChars in following array */
UniChar UniCodeDesc[256]; /* The description in UniCode chars */
};
</PRE>
</TD>
</tr>
</table>
<BR>
<B>DESCRIPTION</B><BR>
<BR>
<P>
The <CODE>CMIterateCMMInfo</CODE> function returns information for all CMMs installed on the system. The caller can pass nil for the <CODE>CMMIterateUPP</CODE> param to simply get a count of CMMs. If a <CODE>CMMIterateUPP</CODE> proc is provided, it will be called once for each CMM installed - with the <CODE>CMMInfo</CODE> structure filled accordingly. The caller can pass a data reference to <CODE>CMIterateCMMInfo</CODE> which will then be passed to the <CODE>CMMIterateUPP</CODE>. This might be used to allow some of the information in the <CODE>CMMInfo</CODE> data structure to be put into a menu, for example, by passing a menu reference as the refcon. Either the proc or the count parameter must be provided. The caller will get a paramErr if both are nil.
<TD>The version of ColorSync installed on the machine is returned here</TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</B><BR>
<BR>
<P>
Returns ColorSync version information. <CODE>CMGetColorSyncVersion</CODE> relieves the Mac OS developer from having to call <CODE>Gestalt</CODE> to find out the version of ColorSync installed on the system. Since no such API exists on other platforms, ColorSync 2.6 introduced a cross-platform way of obtaining this version information.
</P>
<BR>
<TABLE BORDER=0 CELLPADDING=1 width=550>
<TR>
<TD bgcolor="eeeee0">
<P><B>Important Note:</B><BR>
The return value for ColorSync 2.6 is <CODE>0x00026000</CODE> on the Macintosh. This is not consistent with what is currently returned by <CODE>Gestalt</CODE> (<CODE>0x00000260</CODE>). Future versions of ColorSync on the Macintosh will be fixed so they are consistent with <CODE>Gestalt</CODE> return values.<BR>
</TD></TR>
</TABLE>
<BR>
<p id=p1>
<a href="#top">Back to top</a>
</p>
<BR>
<b>Deprecated APIs</b>
<BR>
Support for the following APIs will be eliminated or limited in the future:<BR>
<BR>
<TABLE width=550 border="1">
<TR>
<TH>API</TH><TH>ColorSyncVersion</TH><TH>Supported On Win</TH><TH>Supported on Mac</TH><TH>Reason for Deprecation </TH>
<TD align=center> </TD><TD align=center></TD><TD align=center>- Supported on Win if QTML installed</TD>
</TR>
<TR>
<TD align=center>CMAccelerationLoadTables</td><TD align=center>2.x</td><TD align=center>No</td><TD align=center>No</td><TD align=center>CMM Function - acceleration not platform independent</TD>
</TR>
<TR>
<TD align=center>CMAccelerationCalculateData</td><TD align=center>2.x</td><TD align=center>No</td><TD align=center>No</td><TD align=center>CMM Function - acceleration not platform independent</TD>
</TR>
</TABLE>
<p id=p1>
<a href="#top">Back to top</a>
</p>
<BR>
<A NAME="NewWindows2"></A>
<H2>New ColorSync 2.6 for Windows APIs</H2>
<BR>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
CMError CWMatchHBITMAP (CMWorldRef cw,
HBITMAP hBitmap,
CMBitmapCallBackUPP progressProc,
void *refCon);
</PRE>
</TD>
</tr>
</table>
<BR>
<B>Field Descriptions</B><BR>
<TABLE width=550 border="1">
<TR>
<TD valign=top>cw</TD> <TD valign=top>A reference to the color world in which the matching is to occur.</TD>
</TR>
<TR>
<TD valign=top>hBitmap</TD> <TD valign=top>Handle of a bitmap to be matched. This is a standard Windows Win32 HBITMAP structure.</TD>
</TR>
<TR>
<TD valign=top>progressProc</TD> <TD valign=top>A calling-program-supplied callback function that allows your application to monitor progress or abort the operation as the bitmap colors are matched.</TD>
</TR>
<TR>
<TD valign=top>refCon</TD> <TD valign=top>A reference constant containing data specified by the calling application program.</TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</B><BR>
<BR>
<P>
<CODE>CWMatchHBITMAP</CODE> provides the same kind of matching to platform-specific data as <CODE>CWMatchPixMap</CODE> on Mac OS.
<TD valign=top>createFolder</TD> <TD valign=top>A Boolean specifying whether to create a new ColorSync profiles directory if one cannot be found.</TD>
</TR>
<TR>
<TD valign=top>lpBuffer</TD> <TD valign=top>Contains a pointer to a buffer where you would like the ColorSync folder path returned.</TD>
</TR>
<TR>
<TD valign=top>uSize</TD> <TD valign=top>Contains the size of the buffer.</TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</B><BR>
<BR>
<P>
ColorSync 2.6 now places a "ColorSync Profiles" folder directly in the System Folder for all installed profiles. Like the <CODE>CMGetColorSyncFolderSpec</CODE> function on Mac OS, <CODE>CMGetColorSyncFolderPath</CODE> gives Windows developers a way to find the location of this folder. If the "ColorSync
Profiles" directory does not exist, the <CODE>createFolder</CODE> parameter determines whether or not it is created.
</P>
<BR>
<B>New CMM APIs</B><BR>
<BR>
<P>
The following APIs specify new CMM entry points which ColorSync will call to handle the creation of new color worlds or link profiles as returned by the <CODE>NCWConcatColorWorld</CODE> and <CODE>NCWNewLinkProfile</CODE> functions respectively. These APIs are of interest to CMM developers only.
<TD valign=top>refCon</TD> <TD valign=top>User data passed on to callback procedure.</TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</B><BR>
<BR>
<P>
This is the API which ColorSync calls when an application calls the <SAMP>NCWConcatColorWorld</SAMP> function. The new selector for this function is <CODE>kNCMMConcatInit</CODE>. The CMM is responsible for validating the profiles specified in the profile set
and for building a transform using these profiles. If the CMM cannot build such a transform, it should return a <CODE>cmCantConcatenateErr</CODE> error, or another appropriate error code.
<TD valign=top>refCon</TD> <TD valign=top>User data passed on to callback procedure.</TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</B><BR>
<BR>
<P>
This is the API which ColorSync calls when an application calls the <CODE>NCWNewLinkProfile</CODE> function. The new selector for this function is <CODE>kNCMMNewLinkProfile</CODE>. The CMM is responsible for validating the profiles specified in the profile set
and for building a link profile using these profiles. If the CMM cannot build a link profile, it should return a <CODE>cmCantConcatenateErr</CODE> error, or another appropriate error code. ColorSync will create the profile (via
<CODE>CMNewProfile</CODE>) before calling the CMM, so the CMM need only add the appropriate tags to the profile before returning. ColorSync will also ensure that the tags are written to the profile
by calling <CODE>CMUpdateProfile</CODE>, before returning it to the caller.
</P>
<p id=p1>
<a href="#top">Back to top</a>
</p>
<b>New ColorSync Scripting Library APIs</b>
<BR>
<P>
ColorSync 2.6 provides a new set of scripting library APIs which are designed to give applications access to the same file format utilities provided by the new ColorSync 2.6 AppleEvent terminology. In fact, the code in ColorSync which responds to AppleEvents actually calls this same library. Listed below are the functions introduced in this new scripting library:
<TD valign=top>spec</TD> <TD valign=top>A file specification for the the image file you wish to validate.</TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</B><BR>
<BR>
<P>
This function validates the specified image file. ColorSync will check with any installed scripting plug-ins to see if they recognize the image's file format. If a scripting plug-in is found which recognizes the image's file format, <CODE>CMValidateImage</CODE> will return <CODE>noErr</CODE>. If the image's file format is not recognized, <CODE>CMValidateImage</CODE> will return the <CODE>cmInvalidImageFile</CODE> error.
</P>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
CMError CMGetImageSpace (const FSSpec *spec,
OSType *space);
</PRE>
</TD>
</tr>
</table>
<BR>
<B>Field Descriptions</B><BR>
<BR>
<TABLE width=550 border ="1">
<TR>
<TD>spec</TD> <TD>A file specification for the image file.</TD>
</TR>
<TR>
<TD>space</TD> <TD>The signature of the data color space of the color values of colors for the image file is returned here.</TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</B><BR>
<P>
This function returns the signature of the data color space in which the color values of colors in an image are expressed.
<TD valign=top>specFrom</TD> <TD valign=top>A file specification for the image file.</TD>
</TR>
<TR>
<TD valign=top>specInto</TD> <TD valign=top>If this parameter is a file, it specifies the resulting image. If this parameter is a folder, it specifies the location of the resulting image which will have the same name as the original file. If this parameter is not provided, the original file is modified.</TD>
</TR>
<TR>
<TD valign=top>repl</TD> <TD valign=top>If a file with the same name already exists, it will be replaced if this parameter is set to true.</TD>
</TR>
<TR>
<TD valign=top>embProf</TD> <TD valign=top>The profile to embed in the image.</TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</b><BR>
<BR>
<P>
This function will embed an image with an ICC profile.
</P>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
CMError CMUnembedImage (const FSSpec *specFrom,
const FSSpec *specInto,
Boolean repl);
</PRE>
</TD>
</tr>
</table>
<BR>
<B>Field Descriptions</b><BR>
<BR>
<TABLE width=550 border="1">
<TR>
<TD valign=top>specFrom</TD> <TD valign=top>A file specification for the image file.</TD>
</TR>
<TR>
<TD valign=top>specInto</TD> <TD valign=top>If this parameter is a file, it specifies the resulting image. If this parameter is a folder, it specifies the location of the resulting image which will have the same name as the original file. If this parameter is not provided, the original file is modified.</TD>
</TR>
<TR>
<TD valign=top>repl</TD> <TD valign=top>If a file with the same name already exists, it will be replaced if this parameter is set to true.</TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</b><BR>
<BR>
<P>
This function will remove any ICC profiles embeded in an image.
</P>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
CMError CMMatchImage (const FSSpec *specFrom,
const FSSpec *specInto,
Boolean repl,
UInt32 qual,
CMProfileRef srcProf,
UInt32 srcIntent,
CMProfileRef dstProf);
</PRE>
</TD>
</tr>
</table>
<BR>
<B>Field Descriptions</b><BR>
<BR>
<TABLE width=550 border="1">
<TR>
<TD>specFrom</TD> <TD>A file specification for the image file.</TD>
</TR>
<TR>
<TD>specInto</TD> <TD>If this parameter is a file, it specifies the resulting image. If this parameter is a folder, it specifies the location of the resulting image which will have the same name as the original file. If this parameter is not provided, the original file is modified.</TD>
</TR>
<TR>
<TD>repl</TD> <TD>If a file with the same name already exists, it will be replaced if this parameter is set to true.</TD>
</TR>
<TR>
<TD>qual</TD> <TD>The optional quality for the match - normal, draft or best (<CODE>cmNormalMode</CODE>, <CODE>cmDraftMode</CODE> or <CODE>cmBestMode</CODE>).</TD>
</TR>
<TR>
<TD>srcProf</TD> <TD>The optional source profile for the match. </TD>
</TR>
<TR>
<TD>srcIntent</TD> <TD>The rendering intent for the match - perceptual intent, relative colorimetric intent, saturation intent, or absolute colorimetric intent (<CODE>cmPerceptual</CODE>, <CODE>cmRelativecolorimetric</CODE>, <CODE>cmSaturation</CODE> or <CODE>cmAbsoluteColorimetric</CODE>). </TD>
</TR>
<TR>
<TD>dstProf</TD> <TD>The destination profile for the match. </TD>
<TD>specFrom</TD> <TD>A file specification for the image file.</TD>
</TR>
<TR>
<TD>specInto</TD> <TD>If this parameter is a file, it specifies the resulting image. If this parameter is a folder, it specifies the location of the resulting image which will have the same name as the original file. If this parameter is not provided, the original file is modified.</TD>
</TR>
<TR>
<TD>repl</TD> <TD>If a file with the same name already exists, it will be replaced if this parameter is set to true.</TD>
</TR>
<TR>
<TD>qual</TD> <TD>The optional quality for the match - normal, draft or best (<CODE>cmNormalMode, cmDraftMode</CODE> or <CODE>cmBestMode</CODE>).</TD>
</TR>
<TR>
<TD>srcProf</TD> <TD>The optional source profile for the match. </TD>
</TR>
<TR>
<TD>srcIntent</TD> <TD>The rendering intent for the match between the source and destination profiles - perceptual intent, relative colorimetric intent, saturation intent, or absolute colorimetric intent (<CODE>cmPerceptual, cmRelativecolorimetric, cmSaturation</CODE> or <CODE>cmAbsoluteColorimetric</CODE>). </TD>
</TR>
<TR>
<TD>dstProf</TD> <TD>The destination profile for the match. </TD>
</TR>
<TR>
<TD>prfProf</TD> <TD>The proof profile for the match between the destination and proof profiles. </TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</b><BR>
<BR>
Use this function to proof an image file.<BR>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
CMError CMLinkImage (const FSSpec *specFrom,
const FSSpec *specInto,
Boolean repl,
UInt32 qual,
CMProfileRef lnkProf,
UInt32 lnkIntent);
</PRE>
</TD>
</tr>
</table>
<BR>
<B>Field Descriptions</b><BR>
<BR>
<TABLE width=550 border="1">
<TR>
<TD>specFrom</TD> <TD>A file specification for the image file.</TD>
</TR>
<TR>
<TD>specInto</TD> <TD>If this parameter is a file, it specifies the resulting image. If this parameter is a folder, it specifies the location of the resulting image which will have the same name as the original file. If this parameter is not provided, the original file is modified.</TD>
</TR>
<TR>
<TD>repl</TD> <TD>If a file with the same name already exists, it will be replaced if this parameter is set to true.</TD>
</TR>
<TR>
<TD>qual</TD> <TD>The optional quality for the match - normal, draft or best (<CODE>cmNormalMode, cmDraftMode</CODE> or <CODE>cmBestMode</CODE>).</TD>
</TR>
<TR>
<TD>lnkProf</TD> <TD>The device link profile for the match. </TD>
</TR>
<TR>
<TD>lnkIntent</TD> <TD>The rendering intent for the match - perceptual intent, relative colorimetric intent, saturation intent or absolute colorimetric intent (<CODE>cmPerceptual, cmRelativecolorimetric, cmSaturation</CODE> or <CODE>cmAbsoluteColorimetric</CODE>). </TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</b><BR>
<BR>
<P>
Use this function to match an image file with a device link profile.
<TD>specFrom</TD> <TD>A file specification for the image file.</TD>
</TR>
<TR>
<TD>specInto</TD> <TD>If this parameter is a file, it specifies the resulting image. If this parameter is a folder, it specifies the location of the resulting image which will have the same name as the original file. If this parameter is not provided, the original file is modified.</TD>
</TR>
<TR>
<TD>repl</TD> <TD>If a file with the same name already exists, it will be replaced if this parameter is set to true.</TD>
</TR>
<TR>
<TD>index</TD> <TD>The numeric index of the profile to set. </TD>
</TR>
<TR>
<TD>prof</TD> <TD>The profile to set at the index designated by the index parameter. </TD>
</TR>
</TABLE>
<BR>
<B>DESCRIPTION</b><BR>
<BR>
<P>
Use this function to set a specific embeded profile for a given image.
</P>
<BR>
<B>New CMBitmap Types</B><BR>
<BR>
<P>
Several new <CODE>CMBitmap</CODE> spaces were added in ColorSync 2.6 (see below) to provide developers with a wide range of data formats appropriate for multiple platforms. Both the Mac and Windows
versions of ColorSync 2.6 support all these bitmap formats.
</P>
<P>
Several bitmap spaces now can have a new space attribute flag <CODE>cmLittleEndianPacking</CODE> set to indicate Little-Endian data. Another new variant <CODE>cmReverseChannelPacking</CODE>, which can apply to just about all of the new and old spaces is a "reverse channels" attribute.
</P>
<BR>
<B>Bitmap spaces supported in ColorSync 2.5</B><BR>
<B>ICC Profile Description (<CODE>'desc'</CODE>) Tag Handling</B><BR>
<BR>
<P>
One important change in the recent release of ColorSync (version 2.6) is how it handles the description (<CODE>'desc'</CODE>) tag of ICC profiles.
</P>
<P>
The <CODE>'desc'</CODE> tag of a profile, as defined by the ICC, contains up to three strings. The first is a required 7-bit Roman ASCII string. The second is an optional localized Unicode string. The third, also optional, is a localized string in Mac script-code format. Applications typically use one of the available strings to show the name of profiles in a list or pop-up menu. There are a few other important devilish details in the ICC definition of the <CODE>'desc'</CODE> tag. One is that all three strings must be null terminated. Another is that all three strings are preceded by a character count that includes the null terminator. It is also worth noting that for the Unicode string, the character count must not be confused with a byte count because each Unicode character requires two bytes.
</P>
<P>
Previous releases of ColorSync only make partial use of this tag and, as a result, only performed limited error checking on its contents. For example, The ColorSync function <CODE>CMGetScriptProfileDescription</CODE> would return the Mac script-code from a profile if it was present and, if not, it would return the 7-bit Roman ASCII string. The Unicode string was simply ignored and in some cases, if the Unicode and/or Mac script-code string were non-compliant, ColorSync would return garbage (or the ASCII string if you were lucky) without returning <CODE>cmProfileErr</CODE> code.
</P>
<P>
ColorSync 2.6 is the first release of the technology that was designed to run both on Mac OS and Windows. Since Mac script-code format strings are not usable on Windows, ColorSync clients need to have access to the localized Unicode string. (Unicode strings are also becoming more usable on Macs.) For this reason a new call, <CODE>CMGetProfileDescriptions</CODE>, was added to access all three possible strings. In doing so much stricter attention
had to be paid to the compliance of the <CODE>'desc'</CODE> tag. For example, if either the ASCII string or the Mac script-code strings is not null terminated, or if any of the string's character counts are invalid or beyond the range of the <CODE>'desc'</CODE> tag, the and <CODE>cmProfileErr</CODE> code is returned.
</P>
<P>
In order to achieve optimal performance when applications add profiles to a list or pop-up menu, ColorSync maintains a cache of all the profiles installed in the "ColorSync Profiles" folder and its sub-directories. Among other things this cache file contains the three possible names of each profile obtained by calling <CODE>CMGetProfileDescriptions</CODE>. If <CODE>CMGetProfileDescriptions</CODE> returns an error because the <CODE>'desc'</CODE> tag is non-compliant, then the profile is not added to the cache. This is why non-compliant profiles, even though they are properly installed in the "ColorSync Profiles" folder, no longer show up in the ColorSync control panel or the ColorSync plug-ins pop-up menus with ColorSync 2.6 installed.
</P>
<P>
The remedy for this problem is to repair the affected profiles. Unfortunately, the "Rename Profile" AppleScript that is installed as part of ColorSync 2.6 can not be used to repair profiles with bad <CODE>'desc'</CODE> tags because it can only operate on profiles in the ColorSync profile cache. Instead, a simple stand-alone tool called "Profile First Aid" to verify and repair any profile will be made available on the the ColorSync web site <<A HREF="http://www.apple.com/colorsync">http://www.apple.com/colorsync</A>>.
</P><BR>
<p id=p1>
<a href="#top">Back to top</a>
</p>
<A NAME="Compatibility"></A>
<H2>ColorSync 2.6 for Macintosh Compatibility Issues</H2><BR>
<B>ColorSync 1.X/2.X Support</B><BR>
<P>
Support for version 1.0 profiles and hybrid (1.0/2.0) color worlds has been removed in ColorSync 2.6 for Macintosh. ColorSync 1.0 profiles, APIs and CMMs are not supported.
</P>
<B>CMM</B><BR>
<P>
No longer required to support ColorSync 1.0 Profiles. Existing CMMs will be compatible.
</P>
<P>
New CMM APIs: <CODE>NCMConcatInit</CODE>, <CODE>NCMMNewLinkProfile</CODE> (see section "<A HREF="#NewAPIs">New CMM APIs</A>" for the details) which a CMM may choose to implement. If a given CMM does not implement these new APIs, the default CMM is invoked instead.
</P>
<B>Profile Searching</B><BR>
<P>
ColorSync 2.6 will support new profile locations (System Folder) for Profile searches made with the search functions (<CODE>CMNewProfileSearch</CODE>, etc.). Profiles in subfolders within the profiles folder will be found as well.
</P>
<BR>
<B>Color Worlds</B><BR>
<P>
New API <CODE>NCWConcatColorWorld</CODE> (see section "<A HREF="#NewAPIs">New ColorSync 2.6 APIs</A>" for the details) puts power and responsibility of color world design into the hands of developers. Callers can select which profile
tags and rendering intents to use. It also allows for new combinations of profiles which were previously not supported (e.g., more than one device-link profile).
</P>
<BR>
<B>QuickDraw Matching</B><BR>
<BR>
2.X QuickDraw calls will continue to be supported (<CODE>N/NCMBeginMatching</CODE>, <CODE>CMEndMatching</CODE>, <CODE>N/CMDrawMatchedPicture</CODE>, <CODE>CWMatchPixMap</CODE>, <CODE>CWCheckPixMap</CODE>).<BR>
<BR>
<B>Scripting & File Formats</B><BR>
<BR>
JPEG, GIF as well as TIFF file format plug-ins are now supported.<BR>
<BR>
<B>Endian Issues</B>
<P>
If an API returns data in a structure, the data will be in the proper endian-ness for the platform i.e., Big-Endian on the Mac, Little-Endian under Windows. For example, the <CODE>CMGetCWInfo</CODE> function returns data in a <CODE>CMCWInfoRecord</CODE> structure. If this function is called on a Macintosh, the data in the structure would
be returned in Big-Endian format.
</P>
<P>
If data is passed to or returned by an API as simply a stream of bytes, the data is assumed to be in Big-Endian format. It is the caller's responsibility to convert from native Endian to Big-Endian format.
</P>
<BR><p id=p1>
<a href="#top">Back to top</a>
</p>
<A NAME="WinCompatibility"></A>
<H2>ColorSync 2.6 for Windows Compatibility Issues</H2>
<BR>
<B>CMM</B><BR>
<BR>
CMMs need only support the following entry points:<BR>
<CODE>NCMConcatInit</CODE>, <CODE>NCMMNewLinkProfile</CODE> (see section "<A HREF="#NewAPIs">New CMM APIs</A>" for the details) which a CMM may choose to implement. If a given CMM does not implement these new APIs, the default CMM is invoked instead.
</P>
<BR>
<B>ColorSync 1.X/2.X Support</B><BR>
<BR>
Applications writing to the 2.X APIs will require minimal changes to work.<BR>
ColorSync 1.0 Profiles, APIs and CMMs are not supported.<BR>
<BR>
<B>Profile Access</B><BR>
<P>
ColorSync 2.6 places a "ColorSync Profiles" folder directly in the System Folder. A new location type <CODE>CMPathLocation</CODE> (see "New <CODE>CMProfileLocation</CODE> Types" below) describing the Windows file system specification for this folder has been added to the <CODE>CMProfileLocation</CODE> structure.
</P>
<BR>
<B>New CMProfileLocation Types</B><BR>
<BR>
<CODE>CMProfileLocation</CODE> Expanded - new location types have been added to the <CODE>CMProfileLocation</CODE> structure to give developers a way to specify profiles on Windows systems.<BR>
<BR>
Current Location types:<BR>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
CMFileLocation
CMHandleLocation
CMPtrLocation
CMProcedureLocation
</PRE>
</TD>
</tr>
</table>
<BR>
New Location types:<BR>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
CMPathLocation (specify path as string of chars)
CMBufferLocation (contains ptr and size)
</PRE>
</TD>
</tr>
</table>
<BR>
<TABLE BORDER=0 CELLPADDING=1>
<TR>
<TD bgcolor="EEEEE0">
<PRE>
#define CS_MAX_PATH 256 // How many chars allowed in path name
struct CMPathLocation {
char path[CS_MAX_PATH]; // A complete path
};
struct CMBufferLocation {
void * buffer; // Ptr to profile data
UInt32 size; // Size of Ptr
};
union CMProfLoc {
CMFileLocation fileLoc;
CMHandleLocation handleLoc;
CMPtrLocation ptrLoc;
CMProcedureLocation procLoc;
CMPathLocation pathLoc;
CMBufferLocation bufferLoc;
};
enum {
cmNoProfileBase = 0,
cmFileBasedProfile = 1,
cmHandleBasedProfile = 2,
cmPtrBasedProfile = 3,
cmProcedureBasedProfile = 4,
cmPathBasedProfile = 5,
cmBufferBasedProfile = 6
};
</PRE>
</TD>
</tr>
</table>
<BR>
<B>Profile Searching</B><BR>
<BR>
<P>
ColorSync 2.6 for Windows supports standard locations (System Folder) for Profile searches.
</P>
<BR>
<B>QuickDraw Matching</B><BR>
<BR>
ColorSync 2.6 for Windows does not support the following APIs:<BR>
PixMaps can easily be matched via the <CODE>CMBitMap</CODE> routines.<BR>
<BR>
<B>Win32 Matching</B><BR>
<BR>
<P>
New API <CODE>CWMatchHBITMAP</CODE> (see section "<A HREF="#NewAPIs">New ColorSync 2.6 APIs</A>" above) supports direct matching/checking of Windows <CODE>HBitMap</CODE> structure.
</P>
<BR>
<B>Endian Issues</B><BR>
<BR>
<P>
If an API returns data in a structure, the data will be in the proper endian-ness for the platform i.e., Big-Endian on the Mac, Little-Endian under Windows. For example, the <CODE>CMGetCWInfo</CODE> function returns data in a <CODE>CMCWInfoRecord</CODE> structure. If this function is called on a Windows machine, the data in the structure
would be returned in Little-Endian format.
</P>
<P>
If data is passed to or returned by an API as simply a stream of bytes, the data is assumed to be in Big-Endian format. It is the caller's responsibility to convert from native Endian to Big-Endian format.
</P></TD>
</TR>
</TABLE>
<p id=p1>
<a href="#top">Back to top</a>
</p>
<A NAME="References"></A><BR>
<H3>Further References</H3>
<P><TABLE BORDER=0 CELLPADDING=1 WIDTH=498>
<TR>
<TD bgcolor="eeeee0">
<UL>
<LI><A HREF="/macos/color.html">Inside Macintosh:Managing Color With ColorSync.</A>
</UL>
</TD></TR>
</TABLE><BR>
<p id=p1>
<a href="#top">Back to top</a>
</p>
<H3>Change History</H3>
<P><TABLE BORDER=0 WIDTH=498>
<TR>
<TD bgcolor="eeeee0">
<UL>
<LI>Originally written in April 1999 by Scott Kuechle.